#include <linux/module.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/gpio-bank-n.h>
#include <mach/regs-gpio.h>
#include <linux/io.h>

struct input_dev *ipt;
char *name	= "ipt";

irqreturn_t isr0(int irq,void *val)
{
	unsigned gpn = ioread32(S3C64XX_GPNDAT);
	input_report_key(ipt, BTN_0, ((gpn & 0xf) != 0xf));
	return IRQ_HANDLED;
}
irqreturn_t isr1(int irq,void *val)
{
	unsigned gpn = readl(S3C64XX_GPNDAT);
	input_report_key(ipt, BTN_1, ((gpn & 0xf) != 0xf));
	return IRQ_HANDLED;
}
irqreturn_t isr2(int irq,void *val)
{
	unsigned gpn = readl(S3C64XX_GPNDAT);
	input_report_key(ipt, BTN_2, ((gpn & 0xf) != 0xf));
	return IRQ_HANDLED;
}
irqreturn_t isr3(int irq,void *val)
{
	unsigned gpn = readl(S3C64XX_GPNDAT);
	input_report_key(ipt, BTN_3, ((gpn & 0xf) != 0xf));
	return IRQ_HANDLED;
}

int __init btn_init(void)
{
	int ret;
	//1.
	ipt	= input_allocate_device();

	//2.
	ipt->evbit[BIT_WORD(EV_SYN)] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY);
	ipt->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0) | BIT_MASK(BTN_1)
		| BIT_MASK(BTN_2) | BIT_MASK(BTN_3);

	ipt->name		= name;
	ipt->id.bustype = BUS_RS232;
	ipt->id.vendor	= 0xabcd;
	ipt->id.product = 0x6789;
	ipt->id.version = 0x0001;

	//3.
	ret = input_register_device(ipt);
	if(ret)
		printk("input_register_device failed\n");

	//4.
	ret = request_irq(IRQ_EINT(0), isr0, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, name, ipt);
	ret |= request_irq(IRQ_EINT(1), isr1, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, name, ipt);
	ret |= request_irq(IRQ_EINT(2), isr2, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, name, ipt);
	ret |= request_irq(IRQ_EINT(3), isr3, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, name, ipt);

	if (ret)
		printk("request irq failed\n");

	return 0;
}

void __exit btn_exit(void)
{
	int i;
	
	for(i = 0; i < 4; i++)
		free_irq(IRQ_EINT(i), ipt);
		
	input_unregister_device(ipt);

	input_free_device(ipt);
}

MODULE_LICENSE("GPL");
module_init(btn_init);
module_exit(btn_exit);
